package com.huanuo.internetofthings.realm;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.unicorn.framework.core.exception.PendingException;

import com.huanuo.internetofthings.bo.resources.Resources;
import com.huanuo.internetofthings.bo.userCredentials.UserCredentials;
import com.huanuo.internetofthings.bo.userRole.UserRole;
import com.huanuo.internetofthings.service.resources.UserResourcesFacadeService;
import com.huanuo.internetofthings.service.role.UserRoleFacadeService;
import com.huanuo.internetofthings.service.user.UserCredentialsService;

@Component
public class UserAuthRealm extends AuthorizingRealm {
	private static final Logger log = LoggerFactory.getLogger(UserAuthRealm.class);

	@Autowired
	private UserCredentialsService userCredentialsService;

	@Autowired
	private UserRoleFacadeService userRoleFacadeService;

	@Autowired
	private UserResourcesFacadeService userResourcesFacadeService;

	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
		String userName = (String) arg0.getPrincipal();
		if(StringUtils.isBlank(userName)){
			 log.error("用戶名不能为空");
			throw new AuthenticationException();
		}
		UserCredentials userCredentials = new UserCredentials();
		userCredentials.setUserIdentity(userName);
		try {
			userCredentials = userCredentialsService.getUserCredentials(userCredentials);
		} catch (PendingException e) {
			log.error("获取用户凭证失败", e);
			throw new AuthenticationException(e);
		}
		String accountPassword = userCredentials.getPassword();
		String salt = userCredentials.getSalt();
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, accountPassword,
				ByteSource.Util.bytes(salt), getName());
		return simpleAuthenticationInfo;
	}

	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String userName = (String) principals.getPrimaryPrincipal();

		Set<String> roles = new HashSet<>();
		Set<String> permissions = new HashSet<>();
		try {
			roles.addAll(getRoles(userName));
			permissions.addAll(getPermissions(userName));
		} catch (PendingException e) {
			log.error("获取用户角色或资源失败", e);
		}

		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		simpleAuthorizationInfo.setStringPermissions(permissions);
		simpleAuthorizationInfo.setRoles(roles);

		return simpleAuthorizationInfo;
	}

	private List<String> getRoles(String userName) throws PendingException {
		UserRole userRole = new UserRole();
		userRole.setUserIdentity(userName);
		return userRoleFacadeService.getUserRoleList(userRole);
	}

	private List<String> getPermissions(String userName) throws PendingException {
		UserRole userRole = new UserRole();
		userRole.setUserIdentity(userName);
		List<Resources> resourcesList=userResourcesFacadeService.getUserResourcesList(userRole);
		return resourcesList.stream().map(resources->resources.getPermissionIdentification()).collect(Collectors.toList());
	}
}